package chat;

import gui.GUIHandler;
import gui.GUIManager;

import java.awt.Component;
import java.io.UnsupportedEncodingException;
import java.util.Hashtable;

import javax.swing.JOptionPane;

import user.UserData;

import chat.components.ChatWindow;

import app.AppGlobals;

import network.ChannelData;
import network.ChatMessage;
import network.LogoutData;
import network.PacketCommand;
import network.enums.ServerPackets;

public class ChatHandler {
	
	public static Hashtable<String,ChatWindow> chatTabChannelWindows = new Hashtable<String,ChatWindow>();
	public static boolean autoScroll = true;
	
	public static void addUserList(UserData[] users){
		AppGlobals.userList.clear();
		if(AppGlobals.userList != null){
			for (int i = 0; i < users.length; i++)
				addUser(users[i]);
		}
	}
	
	public static void addFriendList(String[] users){
		for (int i = 0; i < users.length; i++)
			addFriend(users[i]);
	}
	
	public static void addTeamList(String[] users){
		for (int i = 0; i < users.length; i++)
			addTeamMember(users[i]);
	}
	
	public static void addIgnoreList(String[] users){
		for (int i = 0; i < users.length; i++)
			addIgnore(users[i]);
	}
	
	public static void addUser(UserData user){
		if(AppGlobals.userList != null){
			if(!AppGlobals.userList.contains(user.username)){
				AppGlobals.userList.put(user.username, user);
				if(!AppGlobals.userListModel.contains(user.username))
					AppGlobals.userListModel.addElement(user.username);
				//check if user is in your team and exists or if they left
			} else AppGlobals.userList.put(user.username, user);
		}	
	}
	
	public static void removeUser(LogoutData user){
		if(AppGlobals.userList != null){
			if(AppGlobals.userList.containsKey(user.username)){
				if(AppGlobals.userList.get(user.username).loginID == user.loginID){
					AppGlobals.userList.remove(user.username);
				if(AppGlobals.userListModel.contains(user.username))
					AppGlobals.userListModel.removeElement(user.username);
				}

				//updateUserListbox();
			}
		}	
	}
	
	public static void addFriend(String user){
		if(AppGlobals.friendListModel != null){
			if(!AppGlobals.friendListModel.contains(user))
				AppGlobals.friendListModel.addElement(user);
		}
	}
	
	public static void removeFriend(String user){
		if(AppGlobals.friendListModel != null){
			if(AppGlobals.friendListModel.contains(user))
				AppGlobals.friendListModel.removeElement(user);
		}
	}
	
	public static void addTeamMember(String user){
		if(AppGlobals.teamListModel != null){
			if(!AppGlobals.teamListModel.contains(user))
				AppGlobals.teamListModel.addElement(user);
		}
	}
	
	public static void removeTeamMember(String user){
		if(AppGlobals.teamListModel != null){
			if(AppGlobals.teamListModel.contains(user))
				AppGlobals.teamListModel.removeElement(user);
		}
	}
	
	public static void addIgnore(String user){
		if(AppGlobals.ignoreListModel != null){
			if(!AppGlobals.ignoreListModel.contains(user))
				AppGlobals.ignoreListModel.addElement(user);
		}
	}
	
	public static void removeIgnore(String user){
		if(AppGlobals.ignoreListModel != null){
			if(AppGlobals.ignoreListModel.contains(user))
				AppGlobals.ignoreListModel.removeElement(user);
		}
	}
	
	public static void writeSystemMessage(String message){
		writeMessage(new ChatMessage(message, MessageType.System.toString(), MessageType.System.getValue(), CommandType.None.getValue()));
	}
	
	public static void writeMessage(ChatMessage message){
		
		if(message.channel == null || message.from == null){
			if(getSelectedChatWindow() == null){
				createChatTab(MessageType.fromInt(message.type).toString(),false,false);
				chatTabChannelWindows.get(message.channel).writeMessage(message,autoScroll);
			}
			else getSelectedChatWindow().writeMessage(message,autoScroll);
		}
		else if(chatTabChannelWindows.containsKey(message.channel))
			chatTabChannelWindows.get(message.channel).writeMessage(message,autoScroll);
		else
		{
			createChatTab(message.channel,false,false);
			chatTabChannelWindows.get(message.channel).writeMessage(message,autoScroll);
		}
	}
	
	public static void createChatTab(String name, boolean isPrivate, boolean isSystem){
		if(chatTabChannelWindows.containsKey(name))
			return;
		chatTabChannelWindows.put(name, new ChatWindow(name,isPrivate,isSystem));
		GUIManager.chatTabChatWindows.addTab(name,chatTabChannelWindows.get(name));
		GUIManager.chatTabChatWindows.setSelectedComponent(getChatWindow(name));
	}
	
	public static void removeChatTab(String name){
		if(!chatTabChannelWindows.containsKey(name))
			return;
		chatTabChannelWindows.remove(name);
	    for (int i = 0; i < GUIManager.chatTabChatWindows.getTabCount(); i++) {
	    	if(GUIManager.chatTabChatWindows.getTitleAt(i) == name){
	    		GUIManager.chatTabChatWindows.remove(i);
	    		break;
	    	}
	    }
			
	}
	
	public static void removeChatTab(ChatWindow tab){
		if(tab != null)
			removeChatTab(tab.Name);
	}
	
	public static void sendMessage(String channel, String message, boolean isPrivate){
		
		ChatWindow selectedTab = getSelectedChatWindow();
		
        if (message.startsWith("/")){
            if(!HandleCommand(message, selectedTab)){
                return;
            }
        }
        else{	
        	if (selectedTab == null){
                writeSystemMessage("No channel Selected.");
        		return;
            }else if (selectedTab.isSystemWindow){
                return;
            }else if (selectedTab.isPrivateWindow){
            	writeMessage(
            			new ChatMessage(
            					MessageType.Message.getValue(), 
            					CommandType.None.getValue(), 
            					AppGlobals.localUser, 
            					selectedTab.Name, 
            					message));
            	AppGlobals.gameServer.sendChatMessage(message, channel, 
            			MessageType.PrivateMessage.getValue(), CommandType.None.getValue());
            }else{
                boolean isTeam = selectedTab.Name == MessageType.Team.toString();
            	AppGlobals.gameServer.sendChatMessage(message, channel, 
            			isTeam ? MessageType.Team.getValue() : MessageType.Message.getValue(), CommandType.None.getValue());
            }
        }
	}
	
	
	public static ChatWindow getSelectedChatWindow(){
		if(GUIManager.chatTabChatWindows == null || GUIManager.chatTabChatWindows.getTabCount() == 0)
			return null;
		else return (ChatWindow)GUIManager.chatTabChatWindows.getSelectedComponent();
	}
	
	public static ChatWindow getChatWindow(String name){
		if(chatTabChannelWindows.containsKey(name)){
			return chatTabChannelWindows.get(name);
		} else return null;
	}
	
	public static void createChannelWindow(ChannelData[] channels){
		GUIHandler.launchChannelWindow(channels);
		GUIManager.chatTabChannelBtn.setEnabled(true);
	}
	
	private static boolean HandleCommand(String message, ChatWindow selectedTab){
		String[] parts = message.split(" ");
		String cmd = parts[0].substring(1).toLowerCase();
        switch(cmd){
            case "me":
                if (selectedTab == null){
                	writeSystemMessage("No channel Selected.");
                    return false;
                }
                boolean isTeam = selectedTab.Name == MessageType.Team.toString();
                AppGlobals.gameServer.sendChatMessage(message.substring(parts[0].length()).trim(), selectedTab.Name, 
                		isTeam ? MessageType.Team.getValue() : MessageType.Message.getValue(), CommandType.Me.getValue());
                break;
            case "join":
            	if(parts.length > 1){
            		try {
            			AppGlobals.gameServer.sendPacket(ServerPackets.JoinChannel,
            					message.substring(parts[0].length()).trim().getBytes("UTF-8"));
            		} catch (UnsupportedEncodingException e) {
            			// TODO Auto-generated catch block
            			e.printStackTrace();
            		}
            	}else {
            		writeSystemMessage("Enter channel name.");
            	}
                break;
            case "leave":
                if (selectedTab == null){
                    return false;
                }
                
                if (selectedTab.isPrivateWindow)
                	removeChatTab(selectedTab);
                else
                {
                	if(parts.length > 1){
                		try {
							AppGlobals.gameServer.sendPacket(ServerPackets.LeaveChannel, 
									message.substring(parts[0].length()).trim().getBytes("UTF-8"));
							removeChatTab(selectedTab);
						} catch (UnsupportedEncodingException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
                	}else {
                		try {
							AppGlobals.gameServer.sendPacket(ServerPackets.LeaveChannel, 
									selectedTab.Name.getBytes("UTF-8"));
							removeChatTab(selectedTab);
						} catch (UnsupportedEncodingException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
                	}
                }
                
                break;
            case "users":
            	writeSystemMessage("There's " +AppGlobals.userList.size() + " users online.");
                break;
            case "ping":
            	AppGlobals.gameServer.sendPacket(ServerPackets.Ping);
                break;
            case "autoscroll":
                autoScroll = !autoScroll;
            	writeSystemMessage(autoScroll ? "AutoScroll Enabled." : "AutoScroll Disabled.");
                break;
            case "help":
                writeSystemMessage("-- Basic Commands --");
                writeSystemMessage("/admin - Get admin list");
                writeSystemMessage("/users - Get user count");
                writeSystemMessage("/me - Displays Username + Message");
                writeSystemMessage("/join - Join a other channel");
                writeSystemMessage("/leave - Leave the current channel");
                writeSystemMessage("/autoscroll - Enable/Disable autoscroll");
                writeSystemMessage("/ping - Ping the chat server");
                writeSystemMessage("/pinggame - Ping the game server");
                writeSystemMessage("/help - Displays this list your reading now");
                writeSystemMessage("/uptime - Displays how long the server has been online");

                if (AppGlobals.localUser.rank != 0){
                    writeSystemMessage("-- Donator Commands --");
                    writeSystemMessage("[red][/red] [blue][/blue] [green][/green]- Color tags, wrap your text with them to change its color");
                }

                if (AppGlobals.localUser.rank > 0){
                    writeSystemMessage("-- Level 1 Commands --");
                    writeSystemMessage("/kick username reason - Kick a user");
                    writeSystemMessage("/msg - Send a server message");
                }

                if (AppGlobals.localUser.rank > 1){
                    writeSystemMessage("-- Level 2 Commands --");
                    writeSystemMessage("/ban username reason - Ban a user");
                    writeSystemMessage("/unban username - Unban a user");
                    writeSystemMessage("/ip username - Get a users IP");
                    writeSystemMessage("/banip ip - Ban a IP");
                    writeSystemMessage("/unbanip ip - Unbans IP");
                    writeSystemMessage("/getbanlist - Get ban list");
                }

                if (AppGlobals.localUser.rank == 99){
                    writeSystemMessage("-- Level 99 Commands --");
                    writeSystemMessage("/op username level - Set a users level");
                    writeSystemMessage("/addpoints amount of DevPoints - Give a user DevPoints");
                    writeSystemMessage("/removepoints amount of DevPoints - Remove DevPoints from a user");
                }

                if (AppGlobals.localUser.teamRank >= 0 && AppGlobals.localUser.team != ""){
                    writeSystemMessage("-- Team Commands --");
                    writeSystemMessage("/leaveteam - leave the team");
                }

                if (AppGlobals.localUser.teamRank >= 1){
                    writeSystemMessage("-- Team User Level 1 Commands --");
                    writeSystemMessage("/teamadd username - add a user to the team");
                    writeSystemMessage("/teamremove username - remove a user from the team");
                }

                if (AppGlobals.localUser.teamRank == 99){
                    writeSystemMessage("-- Team User Level 99 Commands --");
                    writeSystemMessage("/teamdisband - disbands the team");
                    writeSystemMessage("/teamop username level - promote user in the team");
                    writeSystemMessage("/teamchangeleader username - change the leader of a team");
                }
                
                break;
            case "teamdisband":
            	if(AppGlobals.localUser.team != "" && AppGlobals.localUser.teamRank == 99){
            		
            		int result = JOptionPane.showConfirmDialog((Component)null,
                		"Confirm team disband", "Disband Team", JOptionPane.YES_NO_OPTION);
                	if (result == 0){
            			try {
            				AppGlobals.gameServer.sendPacket(ServerPackets.ChatCommand, 
            					AppGlobals.gson.toJson(
            							new PacketCommand(cmd.toUpperCase(),message.substring(parts[0].length()).trim())
            							).getBytes("UTF-8"));
            			} catch (UnsupportedEncodingException e) {
            			// TODO Auto-generated catch block
            				e.printStackTrace();
            			}
                	}
            	}
                
                break;
            case "admin":
                String admins = "";
                writeSystemMessage("The following admins are online: " + admins + ".");
                break;
            default:			
            	try {
            		AppGlobals.gameServer.sendPacket(ServerPackets.ChatCommand, 
            				AppGlobals.gson.toJson(
            						new PacketCommand(cmd.toUpperCase(),message.substring(parts[0].length()).trim())
            						).getBytes("UTF-8"));
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
                break;
        }

        return true;
    }
}
